﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace MoneyWentWhere.Utils
{
    public static class LinqExtensionMethods
    {
        public static T MaxOrDefault<T>(this IEnumerable<T> source, T defaultValue)
        {
            if (!source.Any()) { return defaultValue; }
            return source.Max();
        }

        // LINQ debug helper
        public static String ToDisplayString(this IEnumerable source, String listFormat = "{1}:{{{0}}}", String itemFormat = "{0}",
            String nullRep = "null", String separator = ", ")
        {
            StringBuilder sb = new StringBuilder();
            int count = 0;
            foreach (Object item in source)
            {
                if (count != 0) { sb.Append(separator); }

                if (item == null) { sb.Append(nullRep); }
                else { sb.AppendFormat(itemFormat, item); }
                count++;
            }
            return String.Format(listFormat, sb, count);
        }

        // LINQ debug helper
        public static String ToDisplayString<TKey, TElement>(this ILookup<TKey, TElement> source)
        {
            StringBuilder sb = new StringBuilder();
            foreach (var grouping in source)
            {
                sb.Append(grouping.Key + "-->");
                sb.AppendLine(grouping.ToDisplayString(listFormat: "count={1}\r\n{0}", itemFormat: "    {0}", separator: "\r\n"));
            }
            return sb.ToString();
        }

        /// <summary>
        /// Concatenate a single item (e.g. balance line) onto a collection
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="source"></param>
        /// <param name="item"></param>
        /// <returns></returns>
        public static IEnumerable<T> Concat<T>(this IEnumerable<T> source, T item)
        {
            return source.Concat(new T[] { item });
        }
     
        public static TValue GetOrDefault<TKey, TValue>(this IDictionary<TKey, TValue> source, TKey key)
        {
            TValue val;
            if (source.TryGetValue(key, out val)) { return val; }
            return default(TValue);
        }
    }
}
